/* eslint-disable no-prototype-builtins */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react-refresh/only-export-components */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { createContext, useContext, useState, useEffect, type ReactNode, useRef } from 'react'
import { type GridSlicerConfig } from '@/types/GridSlicerConfig'

interface ConfigContextType {
  config: GridSlicerConfig
  updateConfig: (newConfig: Partial<GridSlicerConfig>) => Promise<void>
  saveConfig: () => Promise<void>
}

const ConfigContext = createContext<ConfigContextType | undefined>(undefined)

const defaultConfig: GridSlicerConfig = {
  output_dir: '',
  input_files: {
    dem_tif: '',
    dsm_geo: ''
  },
  bbox: {
    minx: 0.0,
    miny: 0.0,
    maxx: 0.0,
    maxy: 0.0,
    epsg: 3857
  },
  download_output: {
    range_type: 0, // 0: none 1: dsm_geo, 2: bbox
    target_epsg: 4326
  },
  grid: {
    size: 5000,
    pixel_size: 5
  },
  height: {
    minheight: 30,
    maxheight: 40,
    step: 10,
    increment: 10
  },
  slice_output: {
    bbox_type: 0, // 0: dsm_geo 1: tif, 2: union
    target_epsg: 3857
  },
  altitude: {
    layerField: 'Floor',
    height: 3.5,
    base_height: 0,
    elev_mode: 'max' // 高程获取模式，'max'表示包围盒最高点，'center'表示中心点，'min'表示包围盒最低点
  },
  logger: {
    log_level: 'INFO'
  }
}

export const ConfigProvider = ({ children }: { children: ReactNode }) => {
  const [config, setConfig] = useState<GridSlicerConfig>(defaultConfig)
  const configRef = useRef<GridSlicerConfig>(defaultConfig)

  // 初始化时读取配置文件
  useEffect(() => {
    loadConfig()
  }, [])

  // 当config状态更新时，同步更新configRef
  useEffect(() => {
    configRef.current = config
  }, [config])

  // 读取配置文件
  const loadConfig = async () => {
    try {
      const configData = (await window.api.ReadConfigFile()) as GridSlicerConfig
      console.log('Loaded config:', configData)
      if (configData) {
        setConfig(configData)
      }
    } catch (error) {
      console.error('Failed to load config:', error)
    }
  }

  // 更新配置 - 改为异步函数
  const updateConfig = async (newConfig: Partial<GridSlicerConfig>) => {
    return new Promise<void>((resolve) => {
      setConfig((prevConfig) => {
        const updatedConfig = { ...prevConfig }

        const mergeConfig = (target: any, source: any) => {
          for (const key in source) {
            if (source.hasOwnProperty(key)) {
              if (
                source[key] &&
                typeof source[key] === 'object' &&
                !Array.isArray(source[key]) &&
                target[key] &&
                typeof target[key] === 'object' &&
                !Array.isArray(target[key])
              ) {
                mergeConfig(target[key], source[key])
              } else {
                target[key] = source[key]
              }
            }
          }
        }

        mergeConfig(updatedConfig, newConfig)
        configRef.current = updatedConfig
        return updatedConfig
      })

      setTimeout(() => resolve(), 0)
    })
  }

  // 保存配置到文件
  const saveConfig = async () => {
    try {
      const result = await window.api.WriteConfigFile(configRef.current)
      if (result) {
        console.log('Config saved successfully:', configRef.current)
      } else {
        console.error('Failed to save config')
        throw new Error('保存配置文件失败: API返回失败')
      }
    } catch (error) {
      console.error('Failed to save config:', error)
      throw new Error(`保存配置文件失败: ${error}`)
    }
  }

  return (
    <ConfigContext.Provider value={{ config, updateConfig, saveConfig }}>
      {children}
    </ConfigContext.Provider>
  )
}

export const useConfig = () => {
  const context = useContext(ConfigContext)
  if (context === undefined) {
    throw new Error('useConfig 必须在 ConfigProvider 内部使用')
  }
  return context
}
